UNPKG

tree-sitter-dart

Version:

Dart grammar attempt for tree-sitter

1,889 lines (1,710 loc) 69.5 kB
// Using the informal draft spec to support the newest features of dart // https://spec.dart.dev/DartLangSpecDraft.pd /* eslint-disable arrow-parens */ /* eslint-disable camelcase */ /* eslint-disable-next-line spaced-comment */ /// <reference types="tree-sitter-cli/dsl" /> // @ts-check const DIGITS = token(sep1(/[0-9]+/, /_+/)); const HEX_DIGITS = token(sep1(/[A-Fa-f0-9]+/, '_')); // Everything above RelationalTypeCast was incremented from its original value // This was to get type casting issues finally fixed. const DART_PREC = { IMPORT_EXPORT: 19, TYPE_IDENTIFIER: 18, // was: 17 DOT_IDENTIFIER: 19, // was: 18 UNARY_POSTFIX: 17, UNARY_PREFIX: 16, Multiplicative: 15, // *, /, ˜/, % Left Additive: 14, // +, - Left Shift: 13, // <<, >>, >>> Left TYPE_ARGUMENTS: 13, Bitwise_AND: 12, // & Left Bitwise_XOR: 11, // ˆ Left Bitwise_Or: 10, // | Left RelationalTypeCast: 9, // <, >, <=, >=, as, is, is! None 8 RelationalTypeTest: 9, Relational: 8, // <, >, <=, >=, as, is, is! None 8 Equality: 7, // ==, != None 7 Logical_AND: 6, // AND && Left Logical_OR: 5, // Or || Left If: 4, // -null ?? Left Conditional: 3, // e1?e2:e3 Right 3 Cascade: 2, // .. Left Assignment: 1, // =, *=, /=, +=, -=, &=, ˆ=, etc. Right BUILTIN: 0, TRY: 0, // Added by Ben for experimentation. SELECTOR_IN_PRIMARY: 1, SELECTOR_IN_ASSIGNMENT: 0, TYPE_ARGS: 1, }; // TODO: general things to add // both string types // get protocols in classes? // todo: type test operators: as, is, and is! // todo: assignment operators: ??=, and ~/= // todo: ?? operator // todo: cascade notation: dot dot accesses each object // todo: conditional member access: blah?.foo // todo: rethrow keyword // todo: override operator notations // todo: correct import statements to be strings // todo: sync* and async* functions, plus yields // DONE: override shorter constructor notations? module.exports = grammar({ name: 'dart', externals: $ => [ $._template_chars_double, $._template_chars_single, $._template_chars_double_single, $._template_chars_single_single, $._template_chars_raw_slash, $._block_comment, $._documentation_block_comment, ], extras: $ => [ $.comment, $.documentation_comment, /\s/, ], supertypes: $ => [ // $._expression, $._declaration, $._statement, $._literal, // $._primary, // $._type, // $._simple_type, // $._type, ], inline: $ => [ $._ambiguous_name, $._class_member_definition, $._if_null_expression, ], conflicts: $ => [ [$.block, $.set_or_map_literal], [$._primary, $.function_signature], [$._type_name, $._primary, $.function_signature], [$._primary, $._type_name], [$.variable_declaration, $.initialized_variable_definition], [$._final_const_var_or_type, $.function_signature], [$._primary, $._function_formal_parameter], [$._primary, $._simple_formal_parameter], [$._primary, $.labeled_statement], [$._primary, $._type_name, $._function_formal_parameter], [$._final_const_var_or_type, $._function_formal_parameter], [$._primary, $.constructor_param], [$._normal_formal_parameters], [$.postfix_expression], [$._declared_identifier], [$.equality_expression], [$._argument_list], [$.variable_declaration, $.initialized_identifier], [$.declaration, $._external_and_static], [$.method_signature, $._static_or_covariant], [$.constructor_signature, $._formal_parameter_part], // [$._type_not_function, $._type_not_void], [$._cascade_subsection], [$._expression], // [$._real_expression, $._below_relational_expression], [$._postfix_expression], [$._top_level_definition, $.lambda_expression], [$._top_level_definition, $._var_or_type, $.function_signature], [$._var_or_type, $.function_signature], [$._var_or_type, $._function_formal_parameter], [$._var_or_type], [$._top_level_definition, $._var_or_type], [$._top_level_definition, $._final_const_var_or_type], [$._top_level_definition, $.const_object_expression, $._final_const_var_or_type], [$._final_const_var_or_type, $.const_object_expression], [$._final_const_var_or_type], [$.type_parameter, $._type_name], [$.class_definition], [$._normal_formal_parameter], [$.library_name, $.dotted_identifier_list], [$._top_level_definition, $.inferred_type], [$._final_const_var_or_type, $._top_level_definition, $.function_signature], [$._assignable_selector_part, $.selector], [$._assignable_selector_part, $._postfix_expression], [$._assignable_selector_part, $.postfix_expression], [$._primary, $.assignable_expression], [$._simple_formal_parameter, $.assignable_expression], // [$._type_name, $._primary, $.assignable_expression], [$.assignable_expression, $.postfix_expression], [$.assignable_expression, $._postfix_expression], // [$._type_name, $.assignable_expression], // [$._type_name, $.function_signature], [$._type_name, $._function_formal_parameter], [$._type_name], // [$.assignment_expression, $._expression], [$.assignable_expression], [$.method_signature, $.declaration, $._static_or_covariant], [$.type_arguments], [$._primary, $._type_name, $.assignable_expression], [$._primary, $._type_name, $.assignable_expression, $.function_signature], [$._primary, $._type_name, $.assignable_expression, $._function_formal_parameter], [$._type_name, $.function_signature], // [$.relational_operator, $._shift_operator], [$.declaration, $._external], [$.relational_expression], [$.factory_constructor_signature, $.redirecting_factory_constructor_signature], [$._function_type_tail], [$._type_not_void_not_function, $._function_type_tail], [$._type_not_void], [$._type_not_void_not_function], [$.super_formal_parameter, $.unconditional_assignable_selector], // [$.function_signature], ], word: $ => $.identifier, rules: { // Page 188 libraryDeclaration program: $ => seq( optional($.script_tag), optional($.library_name), repeat($.import_or_export), repeat($.part_directive), repeat($.part_of_directive), // The precedence here is to make sure that this rule is matched before any of the _statement rules are matched for testing. repeat(prec.dynamic(22, seq(optional($._metadata), $._top_level_definition))), // for testing: repeat($._statement), optional($._expression), ), // Page 187 topLevelDefinition _top_level_definition: $ => choice( $.class_definition, $.enum_declaration, $.extension_declaration, $.mixin_declaration, $.type_alias, seq( optional($._external_builtin), $.function_signature, $._semicolon, ), seq( optional($._external_builtin), $.getter_signature, $._semicolon, ), seq( optional($._external_builtin), $.setter_signature, $._semicolon, ), seq( $.function_signature, $.function_body, ), seq( $.getter_signature, // optional($._type), // $._get, // $.identifier, $.function_body, ), seq( $.setter_signature, // optional($._type), // $._set, // $.identifier, // $.formal_parameter_list, $.function_body, ), // final or const static final declaration list seq( choice( $.final_builtin, $.const_builtin, ), optional($._type), $.static_final_declaration_list, $._semicolon, ), seq( $._late_builtin, $.final_builtin, optional($._type), $.initialized_identifier_list, $._semicolon, ), seq( optional($._late_builtin), choice($._type, seq($.inferred_type, optional($._type))), $.initialized_identifier_list, $._semicolon, ), ), /** ************************************************************************************************ *********************************Literals********************************************************** *************************************************************************************************** ****These are the Literals from section 16.4-9 (Page 84-110) of the dart specification************* *************************************************************************************************** ***************************************************************************************************/ _literal: $ => choice( $.decimal_integer_literal, $.hex_integer_literal, $.decimal_floating_point_literal, $.true, $.false, $.string_literal, $.null_literal, $.symbol_literal, $.list_literal, $.set_or_map_literal, ), /** **This is the symbol literals from section 16.8 (Page 99) of the dart specification****************/ symbol_literal: $ => seq('#', $.identifier), // symbol literal can also be an operator? /** ************************************************************************************************ *********************************Numeric Literals************************************************** *************************************************************************************************** ****These are the Numeric Literals from section 16.5 (Page 84-85) of the dart specification******** *************************************************************************************************** ***************************************************************************************************/ decimal_integer_literal: _ => token(DIGITS), hex_integer_literal: _ => token(seq( choice('0x', '0X'), HEX_DIGITS, )), decimal_floating_point_literal: _ => token(choice( seq(DIGITS, '.', DIGITS, optional(seq((/[eE]/), optional(choice('-', '+')), DIGITS))), seq('.', DIGITS, optional(seq((/[eE]/), optional(choice('-', '+')), DIGITS))), seq(DIGITS, /[eE]/, optional(choice('-', '+')), DIGITS), seq(DIGITS, optional(seq((/[eE]/), optional(choice('-', '+')), DIGITS))), )), /** ************************************************************************************************ *********************************Boolean Literals************************************************** *************************************************************************************************** ****These are the boolean from section 16.6 (Page 86) of the dart specification******************** *************************************************************************************************** ***************************************************************************************************/ true: _ => prec( DART_PREC.BUILTIN, 'true', ), false: _ => prec( DART_PREC.BUILTIN, 'false', ), /** ************************************************************************************************ *********************************String Parts****************************************************** *************************************************************************************************** ****These are the parts of String from section 16.7 (Page 86-92) of the dart specification********* *************************************************************************************************** ***************************************************************************************************/ string_literal: $ => repeat1( choice( $._string_literal_double_quotes, $._string_literal_single_quotes, $._string_literal_double_quotes_multiple, $._string_literal_single_quotes_multiple, // raw, separate later $._raw_string_literal_double_quotes, $._raw_string_literal_single_quotes, $._raw_string_literal_double_quotes_multiple, $._raw_string_literal_single_quotes_multiple, ), ), _string_literal_double_quotes: $ => seq( '"', repeat( choice( $._template_chars_double_single, '\'', $.escape_sequence, $._sub_string_test, $.template_substitution, ), ), '"', ), _string_literal_single_quotes: $ => seq( '\'', repeat(choice( $._template_chars_single_single, '"', $.escape_sequence, $._sub_string_test, $.template_substitution, )), '\'', ), _string_literal_double_quotes_multiple: $ => prec.left( seq( '"""', repeat(choice( $._template_chars_double, '\'', '\"', $.escape_sequence, $._sub_string_test, $.template_substitution, )), '"""', ), ), _string_literal_single_quotes_multiple: $ => prec.left( seq( '\'\'\'', repeat(choice( $._template_chars_single, '"', '\'', $.escape_sequence, $._sub_string_test, $.template_substitution, )), '\'\'\'', ), ), _raw_string_literal_double_quotes: $ => seq( 'r"', repeat(choice( $._template_chars_double_single, // /[^\n"]*/, '\'', $._template_chars_raw_slash, // '\\', $._unused_escape_sequence, $._sub_string_test, '$', )), '"', ), _raw_string_literal_single_quotes: $ => seq( 'r\'', repeat(choice( $._template_chars_single_single, // /[^\n']/, '"', $._template_chars_raw_slash, // '\\', $._unused_escape_sequence, $._sub_string_test, '$', )), '\'', ), _raw_string_literal_double_quotes_multiple: $ => prec.left( seq( 'r"""', // $._triple_double_quote_end, repeat(choice( $._template_chars_double, '\'', // '\\', $._template_chars_raw_slash, '"', $._unused_escape_sequence, $._sub_string_test, '$', )), '"""', // $._triple_double_quote_end ), ), _raw_string_literal_single_quotes_multiple: $ => prec.left( seq( 'r\'\'\'', // $._triple_quote_end, repeat(choice( $._template_chars_single, '"', '\'', // '\\', $._template_chars_raw_slash, $._unused_escape_sequence, $._sub_string_test, '$', )), '\'\'\'', // $._triple_quote_end ), ), _triple_quote_end: _ => token('\'\'\''), _triple_double_quote_end: _ => token('"""'), template_substitution: $ => seq( '$', choice( seq('{', $._expression, '}'), $.identifier_dollar_escaped, ), ), _sub_string_test: _ => seq('$', /[^a-zA-Z_{]/), _string_interp: _ => /\$((\w+)|\{([^{}]+)\})/, // represents $word or ${word} for now _unused_escape_sequence: _ => token.immediate(seq( '\\', choice( /[^xu0-7]/, /[0-7]{1,3}/, /x[0-9a-fA-F]{2}/, /u[0-9a-fA-F]{4}/, /u{[0-9a-fA-F]+}/, ), )), escape_sequence: $ => $._unused_escape_sequence, /** ************************************************************************************************ *********************************Collection Literals*********************************************** *************************************************************************************************** ****These are the collection literals from section 16.9 (Page 92-108) of the dart specification**** *************************************************************************************************** ***************************************************************************************************/ list_literal: $ => seq( optional($.const_builtin), optional($.type_arguments), '[', commaSepTrailingComma($._element), ']', ), set_or_map_literal: $ => seq( optional($.const_builtin), optional($.type_arguments), '{', commaSepTrailingComma( $._element, ), '}', ), pair: $ => seq( field('key', $._expression), ':', field('value', $._expression), ), // pair_or_element: $ => seq( // field('key', $._expression), // optional( // seq( // ':', // field('value', $._expression) // ) // ) // ), _element: $ => choice( $._expression, $.pair, $.spread_element, $.if_element, $.for_element, ), /** **This is the null literal from section 16.4 (Page 84) of the dart specification****/ null_literal: _ => prec( DART_PREC.BUILTIN, 'null', ), /** ************************************************************************************************ *********************************Expressions******************************************************* *************************************************************************************************** ****These are the expressions from section 16.9 (Page 110-166) of the dart specification*********** *************************************************************************************************** ***************************************************************************************************/ _expression: $ => choice( $.assignment_expression, $.throw_expression, seq( $._real_expression, repeat($.cascade_section), ), ), _expression_without_cascade: $ => choice( $.assignment_expression_without_cascade, $._real_expression, $.throw_expression_without_cascade, ), _real_expression: $ => choice( $.conditional_expression, $.logical_or_expression, $.if_null_expression, $.additive_expression, $.multiplicative_expression, $.relational_expression, $.equality_expression, $.logical_and_expression, $.bitwise_and_expression, $.bitwise_or_expression, $.bitwise_xor_expression, $.shift_expression, $.type_cast_expression, $.type_test_expression, $._unary_expression, ), // _below_relational_expression: $ => choice( // // UNARY_POSTFIX: 16, // // UNARY_PREFIX: 15, // // Multiplicative: 14, // *, /, ˜/, % Left // // Additive: 13, // +, - Left // // Shift: 12, // <<, >>, >>> Left // // Bitwise_AND: 11, // & Left // // Bitwise_XOR: 10, // ˆ Left // // Bitwise_Or: 9 , // | Left // // $.type_cast_expression, // $._unary_expression, // $.multiplicative_expression, // $.additive_expression, // $.shift_expression, // $.bitwise_and_expression, // $.bitwise_or_expression, // $.bitwise_xor_expression, // // ), // // _below_relational_type_cast_expression: $ => prec( // DART_PREC.RelationalTypeCast, // choice( // // UNARY_POSTFIX: 16, // // UNARY_PREFIX: 15, // // Multiplicative: 14, // *, /, ˜/, % Left // // Additive: 13, // +, - Left // // Shift: 12, // <<, >>, >>> Left // // Bitwise_AND: 11, // & Left // // Bitwise_XOR: 10, // ˆ Left // // Bitwise_Or: 9 , // | Left // $._unary_expression, // $.multiplicative_expression, // $.additive_expression, // $.shift_expression, // $.bitwise_and_expression, // $.bitwise_or_expression, // $.bitwise_xor_expression, // // ) // ), throw_expression: $ => seq( 'throw', $._expression, ), throw_expression_without_cascade: $ => seq( 'throw', $._expression_without_cascade, ), // cast_expression: $ => prec(PREC.CAST, seq( // '(', // sep1(field('type', $._type), '&'), // ')', // field('value', $._expression) // )), /** ************************************************************************************************ ***********************Assignment Expressions***************************************************** *************************************************************************************************** ****These are the assignment expressions from section 16.34 (Page 159) of the dart DRAFT********** * specification. (Very different from the formal spec in this instance)**************************** *************************************************************************************************** ***************************************************************************************************/ assignment_expression: $ => prec.right(DART_PREC.Assignment, seq( // right field('left', $.assignable_expression), field('operator', $._assignment_operator), field('right', $._expression), )), assignment_expression_without_cascade: $ => prec.right(DART_PREC.Assignment, seq( // right field('left', $.assignable_expression), field('operator', $._assignment_operator), field('right', $._expression_without_cascade), )), assignable_expression: $ => choice( seq($._primary, $._assignable_selector_part), // dart issue? seq($.super, $.unconditional_assignable_selector), seq($.constructor_invocation, $._assignable_selector_part), $.identifier, ), _assignable_selector_part: $ => seq( repeat($.selector), $._assignable_selector, ), // '+=', '-=', '*=', '/=', '&=', '|=', '^=', '%=', '<<=', '>>=', '>>>=', '??=' // todo: use the op names in place of these. _assignment_operator: _ => choice( '=', // additive operator '+=', '-=', // multiplicative operator '*=', '/=', '%=', '~/=', // shift operator '<<=', '>>=', '>>>=', '&=', '^=', '|=', '??=', ), // binary_expression: $ => choice( // ...[ // ['>', PREC.REL], // ['<', PREC.REL], // ['==', PREC.REL], // ['>=', PREC.REL], // ['<=', PREC.REL], // ['!=', PREC.REL], // ['&&', PREC.AND], // ['||', PREC.OR], // ['+', PREC.PLUS], // ['-', PREC.PLUS], // ['*', PREC.TIMES], // ['/', PREC.TIMES], // ['&', PREC.AND], // ['|', PREC.OR], // ['^', PREC.OR], // ['%', PREC.TIMES], // ['<<', PREC.TIMES], // ['>>', PREC.TIMES], // ['>>>', PREC.TIMES], // ].map(([operator, precedence]) => // prec.left(precedence, seq( // field('left', $._expression), // field('operator', operator), // field('right', $._expression) // )) // )), // instanceof_expression: $ => prec(PREC.REL, seq( // field('left', $._expression), // 'instanceof', // field('right', $._type) // )), lambda_expression: $ => seq( field('parameters', $.function_signature), field( 'body', $.function_body, ), ), function_expression: $ => seq( field('parameters', $._formal_parameter_part), field( 'body', $.function_expression_body, ), ), inferred_parameters: $ => seq( '(', commaSep1($.identifier), ')', ), if_null_expression: $ => prec.left( // left DART_PREC.If, seq( field('first', $._real_expression, // logical_or_expression ), $._if_null_expression, // optional( // $._if_null_expression // ) ), ), _if_null_expression: $ => repeat1( seq( '??', field('second', $._real_expression), ), ), conditional_expression: $ => prec.left( // left DART_PREC.Conditional, seq( // $.if_null_expression, $._real_expression, seq( '?', field('consequence', $._expression_without_cascade), ':', field('alternative', $._expression_without_cascade), ), ), ), logical_or_expression: $ => prec.left( // left DART_PREC.Logical_OR, sep2($._real_expression, '||'), ), logical_and_expression: $ => prec.left( // left DART_PREC.Logical_AND, sep2($._real_expression, '&&'), ), equality_expression: $ => prec( // neither DART_PREC.Equality, choice( seq( // $.relational_expression, $._real_expression, // optional( // // ) $.equality_operator, $._real_expression, // $.relational_expression ), seq( $.super, $.equality_operator, // $.relational_expression $._real_expression, ), ), ), equality_operator: _ => token( choice( '==', '!=', ), ), type_cast_expression: $ => prec.left( DART_PREC.RelationalTypeCast, seq( // $._below_relational_type_cast_expression, $._real_expression, $.type_cast, ), ), type_test_expression: $ => prec( DART_PREC.RelationalTypeTest, seq( // $._below_relational_type_cast_expression, $._real_expression, $.type_test, ), ), // _raw_type_cast: $ => prec.right( // seq( // $._below_relational_type_cast_expression, // $.type_cast, // ) // ), relational_expression: $ => prec( // neither DART_PREC.Relational, choice( // $._raw_type_cast, seq( // $.bitwise_or_expression, // $._below_relational_type_cast_expression, // TODO: The spec says optional but it breaks tests, and I'm not sure in a good way. // Modified to account for type casts being compared relationally! // I am not certain this is what designers intended. (see other comments on github) // optional( $._real_expression, $.relational_operator, $._real_expression, // choice( // $.type_test, // $.type_cast, // seq( // $.relational_operator, // $._real_expression // ) // ) // ), ), // seq( // // $.bitwise_or_expression, // choice( // $._raw_type_cast, // $._below_relational_type_cast_expression // ), // $.relational_operator, // choice( // $._raw_type_cast, // $._below_relational_type_cast_expression // ) // ), seq( $.super, $.relational_operator, $._real_expression, ), ), ), relational_operator: _ => choice( '<', '>', '<=', '>=', ), // BITWISE EXPRESSIONS bitwise_or_expression: $ => binaryRunLeft($._real_expression, '|', $.super, DART_PREC.Bitwise_Or), bitwise_xor_expression: $ => binaryRunLeft($._real_expression, '^', $.super, DART_PREC.Bitwise_XOR), bitwise_and_expression: $ => binaryRunLeft($._real_expression, '&', $.super, DART_PREC.Bitwise_AND), shift_expression: $ => binaryRunLeft($._real_expression, $.shift_operator, $.super, DART_PREC.Shift), additive_expression: $ => binaryRunLeft($._real_expression, $.additive_operator, $.super, DART_PREC.Additive), multiplicative_expression: $ => binaryRunLeft($._unary_expression, $.multiplicative_operator, $.super, DART_PREC.Multiplicative), bitwise_operator: $ => $._bitwise_operator, _bitwise_operator: _ => choice( '&', '^', '|', ), shift_operator: $ => $._shift_operator, _shift_operator: _ => choice( '<<', '>>', '>>>', ), additive_operator: $ => $._additive_operator, _additive_operator: _ => token( choice( '+', '-', ), ), multiplicative_operator: $ => $._multiplicative_operator, _multiplicative_operator: _ => choice( '*', '/', '%', '~/', ), _unary_expression: $ => prec( DART_PREC.UNARY_PREFIX, choice( $._postfix_expression, $.unary_expression, ), ), unary_expression: $ => prec( // neither DART_PREC.UNARY_PREFIX, choice( seq($.prefix_operator, $._unary_expression), $.await_expression, // prec(DART_PREC.UNARY_POSTFIX, $._postfix_expression), seq( choice( $.minus_operator, $.tilde_operator, ), $.super, ), seq( $.increment_operator, $.assignable_expression, ), ), ), _postfix_expression: $ => choice( seq( $._primary, repeat( $.selector, ), ), $.postfix_expression, ), postfix_expression: $ => choice( seq( $.assignable_expression, $.postfix_operator, ), seq( $.constructor_invocation, repeat( $.selector, ), ), ), postfix_operator: $ => $.increment_operator, increment_operator: _ => token(choice( '++', '--', )), spread_element: $ => seq( '...', optional('?'), $._expression, ), selector: $ => choice( // '!', $._exclamation_operator, $._assignable_selector, $.argument_part, ), prefix_operator: $ => choice( $.minus_operator, $.negation_operator, $.tilde_operator, ), minus_operator: _ => '-', negation_operator: $ => $._exclamation_operator, _exclamation_operator: _ => '!', tilde_operator: _ => '~', await_expression: $ => seq( 'await', $._unary_expression, ), type_test: $ => seq( $.is_operator, $._type_not_void, ), is_operator: $ => seq( token('is'), optional( $._exclamation_operator, ), ), type_cast: $ => seq( $.as_operator, $._type_not_void, ), as_operator: _ => token('as'), new_expression: $ => seq( $._new_builtin, $._type_not_void, optional( $._dot_identifier, ), $.arguments, ), _dot_identifier: $ => prec.dynamic( DART_PREC.DOT_IDENTIFIER, seq( '.', $.identifier, ), ), const_object_expression: $ => seq( $.const_builtin, $._type_not_void, optional( $._dot_identifier, ), $.arguments, ), _primary: $ => choice( $._literal, $.function_expression, $.identifier, $.new_expression, $.const_object_expression, $.parenthesized_expression, // $.class_literal, $.this, seq( $.super, $.unconditional_assignable_selector, ), // $.object_creation_expression, // $.field_access, // $.array_access, // $.method_invocation, // $.method_reference, ), parenthesized_expression: $ => seq('(', $._expression, ')'), _compound_access: _ => choice('.', '?.'), constructor_invocation: $ => seq( $._type_name, $.type_arguments, '.', $.identifier, $.arguments, ), arguments: $ => seq('(', optional( seq( $._argument_list, optional( ',', ), ), ), ')'), _argument_list: $ => choice( commaSep1($.named_argument), seq(commaSep1($.argument), repeat( seq( ',', commaSep1($.named_argument), ), ), ), ), argument: $ => $._expression, named_argument: $ => seq($.label, $._expression), cascade_section: $ => prec.left( DART_PREC.Cascade, seq( choice('..', '?..'), $.cascade_selector, repeat($.argument_part), repeat( $._cascade_subsection, ), optional( $._cascade_assignment_section, ), ), ), // prec.left( // DART_PREC.Cascade, // ), _cascade_subsection: $ => seq( $._assignable_selector, repeat($.argument_part), ), _cascade_assignment_section: $ => seq( $._assignment_operator, $._expression_without_cascade, ), index_selector: $ => seq('[', $._expression, ']'), cascade_selector: $ => choice( seq( optional($._nullable_type), $.index_selector, ), $.identifier, ), argument_part: $ => seq( optional( $.type_arguments, ), // seq( // $.type_arguments, // $.arguments // ), $.arguments, ), unconditional_assignable_selector: $ => choice( seq( optional($._nullable_type), $.index_selector, ), seq('.', $.identifier), ), conditional_assignable_selector: $ => seq('?.', $.identifier), _assignable_selector: $ => choice( $.unconditional_assignable_selector, $.conditional_assignable_selector, ), type_arguments: $ => choice( // was prec.right // seq( // '<', // '>', // optional($._nullable_type) // ), seq( '<', commaSep($._type), '>', // optional($._nullable_type) ), ), wildcard: $ => seq( optional($._metadata), '?', optional($._wildcard_bounds), ), _wildcard_bounds: $ => choice( seq('extends', $._type), seq($.super, $._type), ), dimensions: $ => prec.right(repeat1( seq(optional($._metadata), '[', ']'), )), // Statements _statement: $ => choice( $.block, prec.dynamic(1, $.local_function_declaration), prec.dynamic(2, $.local_variable_declaration), $.for_statement, $.while_statement, $.do_statement, $.switch_statement, $.if_statement, // TODO: add rethrow statement. // $._declaration, $.try_statement, $.break_statement, $.continue_statement, $.return_statement, $.yield_statement, $.yield_each_statement, $.expression_statement, $.assert_statement, // $.labeled_statement, ), local_function_declaration: $ => seq( optional($._metadata), $.lambda_expression, ), block: $ => seq( '{', repeat($._statement), '}', ), expression_statement: $ => seq( $._expression, $._semicolon, ), labeled_statement: $ => seq( $.identifier, ':', $._statement, ), assert_statement: $ => seq($.assertion, ';'), assertion: $ => seq( $._assert_builtin, $.assertion_arguments, ), assertion_arguments: $ => seq( '(', $._expression, optional( seq( ',', $._expression, ), ), optional(','), ')', ), switch_statement: $ => seq( 'switch', field('condition', $.parenthesized_expression), field('body', $.switch_block), ), switch_block: $ => seq( '{', repeat(choice($.switch_label, $._statement)), '}', ), switch_case: $ => choice( seq(repeat($.label), $.case_builtin, $._expression, ':', repeat1($._statement)), ), default_case: $ => choice( seq(repeat($.label), 'default', ':', repeat1($._statement)), ), switch_label: $ => seq( repeat($.label), choice( seq($.case_builtin, $._expression, ':'), seq('default', ':'), )), do_statement: $ => seq( 'do', field('body', $._statement), 'while', field('condition', $.parenthesized_expression), $._semicolon, ), break_statement: $ => seq($._break_builtin, optional($.identifier), $._semicolon), continue_statement: $ => seq('continue', optional($.identifier), $._semicolon), yield_statement: $ => seq('yield', $._expression, $._semicolon), yield_each_statement: $ => seq('yield', '*', $._expression, $._semicolon), return_statement: $ => seq( 'return', optional($._expression), $._semicolon, ), throw_statement: $ => seq('throw', $._expression, $._semicolon), try_statement: $ => seq( $._try_head, choice( $.finally_clause, seq(repeat1($._on_part), optional($.finally_clause)), ), ), _on_part: $ => choice( seq( $.catch_clause, $.block, ), seq( 'on', $._type_not_void, optional($.catch_clause), $.block, ), ), _try_head: $ => seq( 'try', field('body', $.block), ), catch_clause: $ => seq( 'catch', $.catch_parameters, // field('body', $.block) ), catch_parameters: $ => seq( '(', $.identifier, optional( seq( ',', $.identifier, ), ), ')', ), // catch_formal_parameter: $ => seq( // optional($._metadata), // $.catch_type, // $._variable_declarator_id // ), catch_type: $ => sep1($._type, '|'), finally_clause: $ => seq('finally', $.block), if_element: $ => prec.right(seq( 'if', field('condition', $.parenthesized_expression), field('consequence', $._element), optional(seq('else', field('alternative', $._element))), )), if_statement: $ => prec.right(seq( 'if', field('condition', $.parenthesized_expression), field('consequence', $._statement), optional(seq('else', field('alternative', $._statement))), )), while_statement: $ => seq( 'while', field('condition', $.parenthesized_expression), field('body', $._statement), ), for_statement: $ => seq( optional('await'), 'for', $.for_loop_parts, field('body', $._statement), ), for_loop_parts: $ => seq('(', $._for_loop_parts, ')'), _for_loop_parts: $ => choice( seq( choice( $._declared_identifier, $.identifier, ), 'in', field('value', $._expression), ), seq( optional(choice( field('init', $.local_variable_declaration), seq( commaSep(field('init', $._expression)), $._semicolon, ), )), field('condition', optional($._expression)), $._semicolon, commaSep(field('update', $._expression)), ), ), // support map weirdness? for_element: $ => seq( optional('await'), 'for', $.for_loop_parts, field('body', $._element), ), // Annotations _annotation: $ => choice( $.marker_annotation, $.annotation, ), marker_annotation: $ => seq( '@', field('name', choice($.identifier, $.scoped_identifier)), ), annotation: $ => seq( '@', field('name', choice($.identifier, $.scoped_identifier)), field('arguments', $.arguments), ), // // annotation_argument_list: $ => seq( // '(', // choice( // $._element_value, // commaSep($.element_value_pair), // ), // ')' // ), // element_value_pair: $ => seq( // field('key', $.identifier), // '=', // field('value', $._element_value) // ), // //TODO: remove unnecessary annotation related stuff. // _element_value: $ => prec(1, choice( // $._expression, // $._annotation // )), // element_value_array_initializer: $ => seq( // '{', // commaSep($._element_value), // optional(','), // '}' // ), // Declarations _declaration: $ => prec(1, choice( $.import_specification, $.class_definition, // $.annotation_type_declaration, $.enum_declaration, )), requires_modifier: $ => choice( 'transitive', $._static, ), module_name: $ => choice( $.identifier, seq($.module_name, '.', $.identifier), ), import_or_export: $ => prec( DART_PREC.IMPORT_EXPORT, choice( $.library_import, $.library_export, ), ), library_import: $ => seq( optional($._metadata), $.import_specification, ), library_export: $ => seq( optional($._metadata), $._export, $.configurable_uri, repeat($.combinator), $._semicolon, ), import_specification: $ => choice( seq( $._import, $.configurable_uri, optional( seq( $._as, $.identifier, ), ), repeat($.combinator), $._semicolon, ), seq( $._import, $.uri, $._deferred, $._as, $.identifier, repeat($.combinator), $._semicolon, ), ), part_directive: $ => seq( optional($._metadata), 'part', $.uri, $._semicolon, ), part_of_directive: $ => seq( optional($._metadata), 'part', 'of', choice($.dotted_identifier_list, $.uri), $._semicolon, ), uri: $ => $.string_literal, configurable_uri: $ => seq( $.uri, repeat($.configuration_uri), ), configuration_uri: $ => seq( 'if', $.configuration_uri_condition, $.uri, ), configuration_uri_condition: $ => seq('(', $.uri_test, ')'), uri_test: $ => seq( $.dotted_identifier_list, optional( seq( '==', $.string_literal, ), ), ), combinator: $ => choice( seq('show', $._identifier_list), seq('hide', $._identifier_list), ), _identifier_list: $ => commaSep1($.identifier), asterisk: _ => '*', enum_declaration: $ => seq( 'enum', field('name', $.identifier), field('body', $.enum_body), ), enum_body: $ => seq( '{', commaSep1TrailingComma($.enum_constant), '}', ), enum_constant: $ => (seq( optional($._metadata), field('name', $.identifier), )), type_alias: $ => choice( seq($._typedef, $._type_name, optional($.type_parameters), '=', $.function_type, ';'), seq($._typedef, optional($._type), $._type_name, $._formal_parameter_part, ';'), ), class_definition: $ => choice( seq( optional('abstract'), 'class', field('name', $.identifier), optional(field('type_parameters', $.type_parameters)), optional(field('superclass', $.superclass)), optional(field('interfaces', $.interfaces)), field('body', $.class_body), ), seq( optional($._metadata), optional('abstract'), 'class', $.mixin_application_class, ), ), extension_declaration: $ => choice( seq( 'extension', optional(field('name', $.identifier)), optional(field('type_parameters', $.type_parameters)), 'on', field('class', $._type), field('body', $.extension_body), ), ), _metadata: $ => prec.right(repeat1($._annotation)), type_parameters: $ => seq( '<', commaSep1($.type_parameter), '>', ), type_parameter: $ => seq( optional($._metadata), alias( $.identifier, $.type_identifier), // This is a comment // comment with a link made in https://github.com/flutter/flutter/pull/48547 // Changes made in https://github.com/flutter/flutter/pull/48547 /* This is also a comment */ /* this comment /* // /** ends here: */ optional($._nullable_type), optional($.type_bound), ), type_bound: $ => seq('extends', $._type_not_void), superclass: $ => choice( seq( 'extends', $._type_not_void, optional($.mixins), ), $.mixins, ), mixins: $ => seq( 'with', $._type_not_void_list, ), mixin_application_class: $ => seq( $.identifier, optional($.type_parameters), '=', $.mixin_application, $._semicolon, ), mixin_application: $ => seq( $._type_not_void, $.mixins, optional($.interfaces), ), mixin_declaration: $ => seq( $._mixin, $.identifier, optional($.type_parameters), optional(seq( 'on', $._type_not_void_list, )), optional($.interfaces), $.class_body, ), interfaces: $ => seq( $._implements, $._type_not_void_list, ), interface_type_list: $ => seq( $._type, repeat(seq(',', $._type)), ), class_body: $ => seq( '{', repeat( seq( optional($._metadata), $._class_member_definition, ), ), '}', ), extension_body: $ => seq( '{', repeat( choice( seq(optional($._metadata), $.declaration, $._semicolon), seq( optional($._metadata), seq( $.method_signature, $.function_body, ), ), ), ), '}', ), _class_member_definition: $ => choice( seq($.declaration, $._semicolon), seq( $.method_signature, $.function_body, ), ), getter_signature: $ => seq( optional($._type), $._get, field('name', $.identifier), optional($._native), ), setter_signature: $ => seq( optional($._type), $._set, field('name', $.identifier), $._formal_parameter_part, optional($._native), ), method_signature: $ => choice( seq($.constructor_signature, optional($.initializers)), $.factory_constructor_signature, seq( optional($._static), choice( $.function_signature, $.getter_signature, $.setter_signature, ), ), $.operator_signature, ), declaration: $ => choice( seq($.constant_constructor_signature, optional(choice($.redirection, $.initializers))), seq($.constructor_signature, optional(choice($.redirection, $.initializers))), seq($._external, optional($.const_builtin), $.factory_constructor_signature, ), seq( optional($.const_builtin), $.factory_constructor_signature, $._native, ), seq($._external, $.constant_constructor_signature, ), $.redirecting_factory_constructor_signature, seq($._external, $.constructor_signature, ), seq( optional($._external_builtin), optional($._static), $.getter_signature, ), seq( optional($._external_and_static), $.setter_signature, ), seq( optional($._external), $.operator_signature, ), seq( optional($._external_and_static), $.function_signature, ), // TODO: This should only work with native? seq( $._static, $.function_signature, ), // | static const 〈type〉? 〈staticFinalDeclarationList〉 // | static final 〈type〉? 〈staticFinalDeclarationList〉 // | static late final 〈type〉? 〈initializedIdentifierList〉 // | static late? 〈varOrType〉 〈initializedIdentifierList seq( $._static, choice( seq( $._final_or_const, optional($._type), $.static_final_declaration_list, ), seq( $._late_builtin, choice( seq( $.final_builtin, optional($._type), $.initialized_identifier_list, ), seq( choice( $._type, $.inferred_type, ), $.initialized_identifier_list, ), ), ), seq( choice( $._type, $.inferred_type, ), $.initialized_identifier_list, ), ), ), // | covariant late final 〈type〉? 〈identifierList〉 // | covariant late? 〈varOrType〉 〈initializedIdentifierList〉 seq( $._covariant, choice( seq( $._late_builtin, choice( seq( $.final_builtin, optional($._type), $.identifier_list, ), seq( choice( $._type, $.inferred_type, ), $.initialized_identifier_list, ), ), ), seq( choice( $._type, $.inferred_type, ), $.initialized_identifier_list, ), ), ), seq( optional($._late_builtin), $.final_builtin, optional($._type), $.initialized_identifier_list, ), seq( optional($._late_builtin), $._var_or_type, $.initialized_identifi